package com.hpf.community.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.hpf.community.annotations.MonitorLog;
import com.hpf.community.constants.CommunityConstants;
import com.hpf.community.enums.LogEnum;
import com.hpf.community.exception.CommonException;
import com.hpf.community.model.ActivityModel;
import com.hpf.community.model.ClassModel;
import com.hpf.community.model.CommunityModel;
import com.hpf.community.model.UserModel;
import com.hpf.community.service.IActivityService;
import com.hpf.community.service.IClassService;
import com.hpf.community.service.ICommunityService;
import com.hpf.community.service.IUserService;
import com.hpf.community.utils.CommonUtils;
import com.hpf.community.utils.SendEmail;
import com.hpf.community.utils.SpringHelperUtils;
import com.hpf.community.utils.StandardResult;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@RestController
public class LoginController {

    private final Logger logger = LoggerFactory.getLogger(LoginController.class);

    @Autowired
    private IUserService userService;

    @Autowired
    private ICommunityService communityService;

    @Autowired
    private IClassService classService;

    @Autowired
    private IActivityService activityService;

    @Autowired
    private SpringHelperUtils springHelperUtils;

    /**
     * 登录功能
     *
     * @param: [name, pass, request]
     * @return: com.hpf.community.utils.StandardResult
     * @author: HPF
     * @date: 2020/4/4 23:42
     */
    @PostMapping("/login")
    @MonitorLog(value = "登录", operateType = LogEnum.LOGIN)
    public StandardResult login(String name, @RequestParam("pass") String pass, String email) {
        //使用shiro做登录认证
        if (StringUtils.isNotBlank(email)) {
            Wrapper<UserModel> wrapper = new EntityWrapper<>();
            wrapper.eq(UserModel.EMAIL, email);
            UserModel userModel = userService.selectOne(wrapper);
            name = userModel.getName();
        }
        UsernamePasswordToken token = new UsernamePasswordToken(name, pass);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
        } catch (IncorrectCredentialsException ice) {
            return StandardResult.faild("密码错误!");
        } catch (UnknownAccountException uae) {
            return StandardResult.faild("用户名不存在或已被禁用!");
        }
        //此为返回给前端并塞值进session中
        Wrapper<UserModel> wrapper = new EntityWrapper<>();
        wrapper.eq(UserModel.NAME, name);
//        wrapper.or();
//        wrapper.eq(UserModel.EMAIL,name);
        UserModel user = userService.selectOne(wrapper);
        subject.getSession().setAttribute("loginUser", user);
        return StandardResult.ok(user);
    }


    /**
     * 登出
     *
     * @param: []
     * @return: com.hpf.community.utils.StandardResult
     * @author: HPF
     * @date: 2020/4/4 23:43
     */
    @PutMapping("/logout")
    @MonitorLog(value = "登出", operateType = LogEnum.LOGOUT)
    public StandardResult loginOut(HttpSession session) {
        try {
            //清除缓存
            session.removeAttribute("loginUser");
            return StandardResult.ok();
        } catch (Exception e) {
            logger.error("异常信息:", e);
            return StandardResult.faild(e);
        }
    }

    /**
     * 获取首页统计的数量
     *
     * @param: []
     * @return: com.hpf.community.utils.StandardResult
     * @author: HPF
     * @date: 2020/4/18 17:09
     */
    @GetMapping("/count")
    public StandardResult selectCount() {
        try {
            Map<String, Integer> map = new HashMap<>();
            //社团数量
            Wrapper<CommunityModel> communityModelWrapper = new EntityWrapper<>();
            communityModelWrapper.eq(CommunityModel.IS_DELETE, CommunityConstants.USER_STATUS_ZC);
            communityModelWrapper.eq(CommunityModel.STATUS, CommunityConstants.USER_STATUS_ZC);
            int comCount = communityService.selectCount(communityModelWrapper);
            map.put("comCount", comCount);
            //成员数量
            Wrapper<UserModel> userModelWrapper = new EntityWrapper<>();
            userModelWrapper.eq(UserModel.IS_DELETE, CommunityConstants.USER_STATUS_ZC);
            userModelWrapper.eq(UserModel.STATUS, CommunityConstants.MEMBER_CHECK_TG);
            userModelWrapper.eq(UserModel.ROLE, CommunityConstants.USER_ROLE_PTCH);
            int userCount = userService.selectCount(userModelWrapper);
            map.put("userCount", userCount);
            //活动数量
            Wrapper<ActivityModel> activityModelWrapper = new EntityWrapper<>();
            activityModelWrapper.eq(ActivityModel.IS_DELETE, CommunityConstants.USER_STATUS_ZC);
            int activityCount = activityService.selectCount(activityModelWrapper);
            map.put("activityCount", activityCount);
            //班级数量
            Wrapper<ClassModel> classModelWrapper = new EntityWrapper<>();
            classModelWrapper.eq(ClassModel.STATUS, CommunityConstants.USER_STATUS_ZC);
            int classCount = classService.selectCount(classModelWrapper);
            map.put("classCount", classCount);
            return StandardResult.ok(map);
        } catch (Exception e) {
            logger.error("异常信息:", e);
            return StandardResult.faild(e);
        }
    }

    /**
     * 邮箱验证登录
     *
     * @param: []
     * @return: com.hpf.community.utils.StandardResult
     * @author: HPF
     * @date: 2020/4/22 10:23
     */
    @GetMapping("/emailCheck")
    public StandardResult emailCheck(String email, String emailCheck, Integer date, HttpSession session) {
        try {
            String emailSession = (String) session.getAttribute("email");//用户邮箱
            Integer loginEmail = (Integer) session.getAttribute("loginEmail");//验证码
            //检查验证码是否过期
            int dateBetween = (DateUtil.toIntSecond(new Date()) - date) / 60;
            if (dateBetween > NumberUtil.parseInt(springHelperUtils.getEffect())) {
                session.removeAttribute("loginEmail");
                session.removeAttribute("email");
                return StandardResult.faild("验证码已失效，请重新获取");
            }
            if (!StringUtils.equals(emailCheck, String.valueOf(loginEmail))) {
                return StandardResult.faild("验证码错误！");
            }
            if (!StringUtils.equals(emailSession, email)) {
                return StandardResult.faild("请检查您的邮箱账户是否正确");
            }
            return StandardResult.ok();
        } catch (Exception e) {
            return StandardResult.faild(e);
        }
    }

    /**
     * 给相应的邮箱发送随机的验证码
     *
     * @param: []
     * @return: com.hpf.community.utils.StandardResult
     * @author: HPF
     * @date: 2020/4/22 10:23
     */
    @GetMapping("/emailRandom")
    public StandardResult emailRandom(HttpSession session, String email) {
        try {
            //获取邮箱要检查是否存在此邮箱账户
            Wrapper<UserModel> wrapper = new EntityWrapper<>();
            wrapper.eq(UserModel.EMAIL, email);
            wrapper.eq(UserModel.IS_DELETE, CommunityConstants.USER_STATUS_ZC);
            wrapper.andNew();
            wrapper.eq(UserModel.ROLE, CommunityConstants.USER_ROLE_HTYH);
            wrapper.or();
            wrapper.eq(UserModel.ROLE, CommunityConstants.USER_ROLE_GLY);
            UserModel userModel = userService.selectOne(wrapper);
            if (null == userModel) {
                return StandardResult.faild("此邮箱未绑定相应账户！");
            }
            int randomInt = RandomUtil.randomInt(1000, 9999);
            session.setAttribute("email", email);
            session.setAttribute("loginEmail", randomInt);
            //发送邮件
            SendEmail.sendEmail(email, springHelperUtils.getEmail(), springHelperUtils.getEmail(), springHelperUtils.getEmailAuth(), "大学生社团管理系统登录验证码", "您的验证码为：" + randomInt + ",此验证码一分钟内有效，为保障账户安全，请不要泄露给他人。");
            return StandardResult.ok(DateUtil.toIntSecond(new Date()));
        } catch (Exception e) {
            return StandardResult.faild(e);
        }
    }


    @PostMapping("/insertList")
    @Transactional(rollbackFor = Exception.class)
    public StandardResult test(@RequestBody List<String> list) {
        logger.info(Thread.currentThread().getName());
        list.stream().parallel().forEach(id -> {
            UserModel userModel = new UserModel();
            userModel.setId(CommonUtils.getUUID());
            userModel.setStatus(id);
            userModel.setName("得得" + id);
            userService.insert(userModel);
            logger.info(Thread.currentThread().getName());
            if (StringUtils.equals(id, "6")) {
                throw new CommonException("test" + id);
            }
        });
        return StandardResult.ok();
    }
}
